﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using GabageFactory.Models;
using GabageFactory.Utiliy.Crypt;

namespace GabageFactory.Controllers
{
    [Authorize]
    public class ReportingController : BaseController
    {
        MessageReposity messageReposity = new MessageReposity();

        ReportingReposity reportingReposity = new ReportingReposity();

        UserReposity userReposity = new UserReposity();

        FactoryReposity factoryReposity = new FactoryReposity();

        StackReposity stackReposity = new StackReposity();

        TailingpondReposity tailingpondReposity = new TailingpondReposity();
        //
        // GET: /Reporting/List/
        public ActionResult List(int? year)
        {
            List<RoleEnum> roles = new List<RoleEnum>();
            roles.Add(RoleEnum.Expert);
            ActionResult result = AllowForRole(roles);
            if (result != null)
            {
                return result;
            }

            if (!year.HasValue)
            {
                year = DateTime.Now.Year;
            }

            reportingReposity.CreateReportings();
            List<int> years = reportingReposity.ListYears().ToList();
            IEnumerable<AnalysisReporting> reportings = reportingReposity.ListReportings(year.Value);
            IEnumerable<User> analyzers = userReposity.ListUsers(GetCurrentUser().FactoryId).Where(u => u.RoleId == (int)RoleEnum.Analyzer);

            ViewData["year"] = year.Value;
            ViewData["years"] = years;
            ViewData["reportings"] = reportings;
            ViewData["analyzers"] = analyzers;

            return View();
        }

        // GET: /Reporting/Own/
        public ActionResult Own(int? year)
        {
            List<RoleEnum> roles = new List<RoleEnum>();
            roles.Add(RoleEnum.Analyzer);
            ActionResult result = AllowForRole(roles);
            if (result != null)
            {
                return result;
            }

            if (!year.HasValue)
            {
                year = DateTime.Now.Year;
            }

            long userId = GetCurrentUser().Id;

            List<int> years = reportingReposity.ListYears().ToList();
            IEnumerable<AnalysisReporting> reportings = reportingReposity.ListReportings(year.Value, userId);

            ViewData["year"] = year.Value;
            ViewData["years"] = years;
            ViewData["reportings"] = reportings;

            return View();
        }

        // GET: /Reporting/Own/
        public ActionResult History(int? year)
        {
            List<RoleEnum> roles = new List<RoleEnum>();
            roles.Add(RoleEnum.Manager);
            roles.Add(RoleEnum.Auditor);
            ActionResult result = AllowForRole(roles);
            if (result != null)
            {
                return result;
            }

            if (!year.HasValue)
            {
                year = DateTime.Now.Year;
            }

            long factoryId = GetCurrentUser().FactoryId;

            List<int> years = reportingReposity.ListYears().ToList();
            IEnumerable<AnalysisReporting> reportings = reportingReposity.ListHistoryReportings(year.Value, factoryId);

            ViewData["year"] = year.Value;
            ViewData["years"] = years;
            ViewData["reportings"] = reportings;

            return View();
        }

        // GET: /Reporting/Own/
        public ActionResult Input(long id)
        {
            List<RoleEnum> roles = new List<RoleEnum>();
            roles.Add(RoleEnum.Analyzer);
            ActionResult result = AllowForRole(roles);
            if (result != null)
            {
                return result;
            }

            long userId = GetCurrentUser().Id;

            analysis_reporting_list r = reportingReposity.GetReportingById(id);

            if (r == null)
            {
                throw new Exception("非法操作，分析报告不存在.");
            }

            if (r.userId != userId)
            {
                throw new Exception("非法操作，不能填写他人的分析报告.");
            }

            ViewData["reporting"] = r;

            if (r.type == 1)
            {
                stack_analysis_detail s =  reportingReposity.GetStackAnalysis(id);
                Stack stack = stackReposity.GetStackById(r.stackId);
                ViewData["stack"] = stack;

                return View("Stack", s);
            }
            else if (r.type == 2)
            {
                tailingpond_analysis_detail t = reportingReposity.GetTailingpondAnalysis(id);
                Tailingpond tailingpond = tailingpondReposity.GetTailingpondById(r.stackId);

                ViewData["tailingpond"] = tailingpond;
                return View("Tailingpond", t);
            }

            throw new Exception("非法操作，分析报告不存在.");
        }

        // GET: /Reporting/View/
        public ActionResult View(long id)
        {
            List<RoleEnum> roles = new List<RoleEnum>();
            roles.Add(RoleEnum.Analyzer);
            roles.Add(RoleEnum.Expert);
            roles.Add(RoleEnum.Auditor);
            roles.Add(RoleEnum.Manager);
            ActionResult result = AllowForRole(roles);
            if (result != null)
            {
                return result;
            }

            analysis_reporting_list r = reportingReposity.GetReportingById(id);

            User analyzer = null;
            User auditor = null;
            if (r.userId.HasValue)
            {
                analyzer = userReposity.GetUserById(r.userId.Value);
            }
            if (r.auditorId.HasValue)
            {
                auditor = userReposity.GetUserById(r.auditorId.Value);
            }

            ViewData["analyzer"] = analyzer;
            ViewData["auditor"] = auditor;

            if (r == null)
            {
                throw new Exception("非法操作，分析报告不存在.");
            }

            ViewData["reporting"] = r;

            if (r.type == 1)
            {
                stack_analysis_detail s = reportingReposity.GetStackAnalysis(id);
                Stack stack = stackReposity.GetStackById(r.stackId);
                ViewData["stack"] = stack;

                return View("StackView", s);
            }
            else if (r.type == 2)
            {
                tailingpond_analysis_detail t = reportingReposity.GetTailingpondAnalysis(id);
                Tailingpond tailingpond = tailingpondReposity.GetTailingpondById(r.stackId);

                ViewData["tailingpond"] = tailingpond;
                return View("TailingpondView", t);
            }

            throw new Exception("非法操作，分析报告不存在.");
        }

        // GET: /Reporting/Query/
        public ActionResult Query(FormCollection form)
        {
            List<RoleEnum> roles = new List<RoleEnum>();
            roles.Add(RoleEnum.Analyzer);
            roles.Add(RoleEnum.Expert);
            roles.Add(RoleEnum.Auditor);
            roles.Add(RoleEnum.Manager);
            ActionResult result = AllowForRole(roles);
            if (result != null)
            {
                return result;
            }

            long factoryId = parseInt(form.Get("factoryId"));
            if (GetCurrentUser().RoleId == (int)RoleEnum.Expert || GetCurrentUser().RoleId == (int)RoleEnum.Analyzer)
            {
                ViewData["showFactory"] = true;
                ShowFactoryList(factoryId, false);
                List<SelectListItem> factories = (List<SelectListItem>)ViewData["factories"];
                SelectListItem item1 = null;
                foreach (SelectListItem item in factories)
                {
                    if (item.Value == "3")
                    {
                        item1 = item;
                        break;
                    }
                }
                if (item1 != null)
                {
                    factories.Remove(item1);
                }
                ViewData["factories"] = factories;
            }
            else
            {
                ViewData["showFactory"] = false;
                factoryId = GetCurrentUser().FactoryId;
            }
            ViewData["factoryId"] = factoryId;

            string sId = form.Get("stackId");
            int id = 0;
            int stype = 0;
            ParseSid(sId, ref id, ref stype);
            ShowStackAndTailingoind(factoryId > 0 ? factoryId : 9999 , 0, id, stype);

            DateTime beginDate = DateTime.Now.AddYears(-1);
            string begin = form.Get("begin");
            if (!string.IsNullOrEmpty(begin))
            {
                DateTime.TryParse(begin + "-01", out beginDate);
            }
            DateTime endDate = DateTime.Now;
            string end = form.Get("end");
            if (!string.IsNullOrEmpty(end))
            {
                DateTime.TryParse(end + "-01", out endDate);
            }

            ViewData["begin"] = beginDate;
            ViewData["end"] = endDate;
            int inNormal = parseInt(form.Get("inNormal"));
            ViewData["inNormal"] = inNormal;
            int stackWater = parseInt(form.Get("stackWater"));
            ViewData["stackWater"] = stackWater;
            int stackBackWater = parseInt(form.Get("stackBackWater"));
            ViewData["stackBackWater"] = stackBackWater;
            int stackSettle = parseInt(form.Get("stackSettle"));
            ViewData["stackSettle"] = stackSettle;
            int stackArdealite = parseInt(form.Get("stackArdealite"));
            ViewData["stackArdealite"] = stackArdealite;
            int stackDitch = parseInt(form.Get("stackDitch"));
            ViewData["stackDitch"] = stackDitch;
            int stackWell = parseInt(form.Get("stackWell"));
            ViewData["stackWell"] = stackWell;
            int stackBase = parseInt(form.Get("stackBase"));
            ViewData["stackBase"] = stackBase;
            int stackDrain = parseInt(form.Get("stackDrain"));
            ViewData["stackDrain"] = stackDrain;
            int tailingpondWater = parseInt(form.Get("tailingpondWater"));
            ViewData["tailingpondWater"] = tailingpondWater;
            int tailingpondBackWater = parseInt(form.Get("tailingpondBackWater"));
            ViewData["tailingpondBackWater"] = tailingpondBackWater;
            int tailingpondDitch = parseInt(form.Get("tailingpondDitch"));
            ViewData["tailingpondDitch"] = tailingpondDitch;
            int tailingpondFilldam = parseInt(form.Get("tailingpondFilldam"));
            ViewData["tailingpondFilldam"] = tailingpondFilldam;

            Pagination pagination = new Pagination();
            pagination.PageNo = parseInt(form.Get("PageNo"));

            if (stype == 0 && id > 0)
            {
                IEnumerable<StackReporting> reportings = reportingReposity.QueryStackReportings(factoryId, id, beginDate, endDate, pagination);
                if (inNormal == 1)
                {
                    if (stackWater == 1)
                    {
                        reportings = reportings.Where(item => item.water == 1);
                    }
                    
                    if (stackBackWater == 1)
                    {
                        reportings = reportings.Where(item => item.backwater == 1);
                    }
                    
                    if (stackSettle == 1)
                    {
                        reportings = reportings.Where(item => item.settle == 1);
                    }

                    if (stackSettle == 1)
                    {
                        reportings = reportings.Where(item => item.ardealite == 1);
                    }
                    
                    if (stackDitch == 1)
                    {
                        reportings = reportings.Where(item => item.ditch == 1);
                    }
                    
                    if (stackWell == 1)
                    {
                        reportings = reportings.Where(item => item.piezometerwell == 1);
                    }

                    if (stackBase == 1)
                    {
                        reportings = reportings.Where(item => item.piezometerbase == 1);
                    }

                    if (stackDrain == 1)
                    {
                        reportings = reportings.Where(item => item.drain == 1);
                    }
                }
                ViewData["reportings"] = reportings;
            }
            else if (stype == 1)
            {
                IEnumerable<TailingpondReporting> reportings = reportingReposity.QueryTailingpondReportings(factoryId, id, beginDate, endDate, pagination);
                if (inNormal == 1)
                {
                    if (tailingpondWater == 1)
                    {
                        reportings = reportings.Where(item => item.water == 1);
                    }
                    
                    if (tailingpondBackWater == 1)
                    {
                        reportings = reportings.Where(item => item.backwater == 1);
                    }

                    if (tailingpondDitch == 1)
                    {
                        reportings = reportings.Where(item => item.ditch == 1);
                    }
                    
                    if (tailingpondFilldam == 1)
                    {
                        reportings = reportings.Where(item => item.filldam == 1);
                    }
                }
                ViewData["reportings"] = reportings;
            }

            ViewData["currentPage"] = pagination.PageNo;
            ViewData["totalPage"] = pagination.TotalPage;
            ViewData["showResults"] = id > 0;
            ViewData["stype"] = stype;

            return View();
        }

        [HttpPost]
        public ActionResult SaveStack(stack_analysis_detail detail, int action, HttpPostedFileWrapper doc)
        {
            List<RoleEnum> roles = new List<RoleEnum>();
            roles.Add(RoleEnum.Analyzer);
            ActionResult result = AllowForRole(roles);
            if (result != null)
            {
                return result;
            }

            stack_analysis_detail old = reportingReposity.GetStackAnalysis(detail.id);
            detail.doc = old.doc;

            if (doc != null)
            {
                string fileName = UploadFile(doc, FileType.Reporting);

                detail.doc = fileName;
            }

            if (!string.IsNullOrEmpty(detail.summary))
            {
                detail.summary = detail.summary.Replace("&lt;", "<").Replace("&gt;", ">").Replace("&amp;", "&");
            }

            if (!string.IsNullOrEmpty(detail.suggestion))
            {
                detail.suggestion = detail.suggestion.Replace("&lt;", "<").Replace("&gt;", ">").Replace("&amp;", "&");
            }

            reportingReposity.DeleteStackAnalysis(old.id);
            reportingReposity.CreateStackAnalysis(detail);

            if (action == 1)
            {
                var r = reportingReposity.GetReportingById(detail.id);
                r.status = 2;
                r.finishedTime = DateTime.Now;
                reportingReposity.UpdateAnalysisReporting(r);
                AddMessage(r, 1);
            }

            return RedirectToAction("Own", new { year = DateTime.Now.Year }); 
        }

        [HttpPost]
        public ActionResult SaveTailingpond(tailingpond_analysis_detail detail, int action, HttpPostedFileWrapper doc)
        {
            List<RoleEnum> roles = new List<RoleEnum>();
            roles.Add(RoleEnum.Analyzer);
            ActionResult result = AllowForRole(roles);
            if (result != null)
            {
                return result;
            }

            tailingpond_analysis_detail old = reportingReposity.GetTailingpondAnalysis(detail.id);
            detail.doc = old.doc;

            if (doc != null)
            {
                string fileName = UploadFile(doc, FileType.Reporting);

                detail.doc = fileName;
            }

            if (!string.IsNullOrEmpty(detail.summary))
            {
                detail.summary = detail.summary.Replace("&lt;", "<").Replace("&gt;", ">").Replace("&amp;", "&");
            }

            if (!string.IsNullOrEmpty(detail.suggestion))
            {
                detail.suggestion = detail.suggestion.Replace("&lt;", "<").Replace("&gt;", ">").Replace("&amp;", "&");
            }

            reportingReposity.DeleteTailingpondAnalysis(old.id);
            reportingReposity.CreateTailingpondAnalysis(detail);

            if (action == 1)
            {
                var r = reportingReposity.GetReportingById(detail.id);
                r.status = 2;
                r.finishedTime = DateTime.Now;
                reportingReposity.UpdateAnalysisReporting(r);
                AddMessage(r, 1);
            }

            return RedirectToAction("Own", new { year = DateTime.Now.Year });
        }

        public ActionResult UploadImage()
        {
            return View();
        }

        [HttpPost]
        public ActionResult UploadImage(HttpPostedFileWrapper image)
        {
            List<RoleEnum> roles = new List<RoleEnum>();
            roles.Add(RoleEnum.Analyzer);
            ActionResult result = AllowForRole(roles);
            if (result != null)
            {
                return result;
            }
            string fileName = null;
            if (image != null)
            {
                fileName = UploadFile(image, FileType.ReportingImage);
                
            }
            ViewData["url"] = fileName;

            return View("UploadSuccess");
        }

        [HttpPost]
        public ActionResult Distribute(FormCollection form)
        {
            List<RoleEnum> roles = new List<RoleEnum>();
            roles.Add(RoleEnum.Expert);
            ActionResult result = AllowForRole(roles);
            if (result != null)
            {
                return result;
            }

            long id = long.Parse(form.Get("id"));
            long userId = long.Parse(form.Get("userId"));
            DateTime finishedDate = DateTime.Parse(form.Get("finishedDate"));

            analysis_reporting_list r = reportingReposity.GetReportingById(id);
            if (r == null)
            {
                throw new Exception("非法操作，参数不正确");
            }

            Message message = messageReposity.FindMessage(GetCurrentUser().FactoryId, id.ToString());
            if (message != null)
            {
                messageReposity.DeleteMessage(message);
            }

            r.userId = userId;
            r.finishedTime = finishedDate.AddSeconds(86399);
            r.status = 1;

            reportingReposity.DistributeReporting(r);

            return RedirectToAction("List", new { year = r.date.Year});
        }

        [HttpPost]
        public ActionResult Modify(long id)
        {
            List<RoleEnum> roles = new List<RoleEnum>();
            roles.Add(RoleEnum.Expert);
            ActionResult result = AllowForRole(roles);
            if (result != null)
            {
                return result;
            }

            analysis_reporting_list r = reportingReposity.GetReportingById(id);
            if (r == null)
            {
                throw new Exception("非法操作，参数不正确");
            }

            r.status = 1;
            reportingReposity.UpdateAnalysisReporting(r);
            Message message = messageReposity.FindMessage(GetCurrentUser().FactoryId, id.ToString());
            if (message != null) {
                messageReposity.DeleteMessage(message);
            }
            return RedirectToAction("List", new { year = r.date.Year });
        }

        [HttpPost]
        public ActionResult Publish(long id, float quality)
        {
            List<RoleEnum> roles = new List<RoleEnum>();
            roles.Add(RoleEnum.Expert);
            ActionResult result = AllowForRole(roles);
            if (result != null)
            {
                return result;
            }

            analysis_reporting_list r = reportingReposity.GetReportingById(id);
            if (r == null)
            {
                throw new Exception("非法操作，参数不正确");
            }

            r.status = 3;
            r.quality = quality;
            r.publishedTime = DateTime.Now;
            r.auditorId = GetCurrentUser().Id;
            reportingReposity.UpdateAnalysisReporting(r);

            Message message = messageReposity.FindMessage(GetCurrentUser().FactoryId, id.ToString());
            if (message != null)
            {
                messageReposity.DeleteMessage(message);
            }
            AddMessage(r, 2);

            return RedirectToAction("List", new { year = r.date.Year });
        }

        private void AddMessage(analysis_reporting_list r, int type)
        {
            Message message = new Message();
            message.attach = r.id.ToString();
            message.FactoryId = type == 2 ? r.factoryId : GetCurrentUser().FactoryId;
            message.priority = 2;
            message.roles = type == 1 ? "7" : "3,6";
            message.type = 1;
            message.publisher = GetCurrentUser().Id;
            message.beginTime = DateTime.Now;
            DateTime tempTime = new DateTime(DateTime.Now.Year, DateTime.Now.Month + 1, 1, 23, 59, 59).AddDays(-1);
            message.endTime = type == 2 ? tempTime : DateTime.Now.AddYears(10);

            Factory factory = factoryReposity.GetFactoryById(r.factoryId);

            string content = "";
            string sName = "";

            if (r.type == 1)
            {
                Stack s = stackReposity.GetStackById(r.stackId);
                sName = s.Name;
            }
            else if (r.type == 2)
            {
                Tailingpond t = tailingpondReposity.GetTailingpondById(r.stackId);
                sName = t.Name;
            }

            string date = "";
            if (type == 1)
            {
                content = "<p><span style='color: #ff0000'><strong>【预发布通知】</strong></span>  {0} 的 {1} {2} 的监控报告已经预发布，请查阅并正式发布。    报告人：  {4}    预发布时间：  {3}  </p>";
                date = r.finishedTime.Value.ToString("yy年MM月dd日hh:mm:ss");
            }
            else
            {
                content = "<p><span style='color: #ff0000'><strong>【月度报告发布】</strong></span>  {0} 的 {1} {2} 的监控报告已经完成，请查阅。发布时间：  {3}  </p>";
                date = r.publishedTime.Value.ToString("yy年MM月dd日hh:mm:ss"); 
            }
            content = string.Format(content, factory.Name, sName, r.date.Year + "年" + r.date.Month + "月", date, GetCurrentUser().RealName + "(" + GetCurrentUser().Name + ")");

            message.content = content;
            messageReposity.CreateMessage(message);
        }
    }
}
